﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Web.Security;

namespace Aj.Core
{

    /// <summary>
    /// 加密函数库
    /// </summary>
    public static class DataCrypto
    {

        /// <summary>
        /// 转换字符到字节数组
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static byte[] TransToByte(this string source)
        {
            return source.TransToByte(System.Text.Encoding.UTF8);
        }
        /// <summary>
        /// 转换字符到字节数组
        /// </summary>
        /// <param name="source"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static byte[] TransToByte(this string source, System.Text.Encoding encoding)
        {
            return encoding.GetBytes(source);
        }
        /// <summary>
        /// 转换字节数组为字符串
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string TransToString(this byte[] source)
        {
            return source.TransToString(System.Text.Encoding.UTF8);
        }
        /// <summary>
        /// 转换字节数组为字符串
        /// </summary>
        /// <param name="source"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static string TransToString(this byte[] source, System.Text.Encoding encoding)
        {
            return encoding.GetString(source);
        }

        /// <summary>
        /// 获得加密密钥
        /// </summary>
        /// <param name="len"></param>
        /// <returns></returns>
        private static byte[] GetLegalKey(int len)
        {
            string sTemp = "7951429DF4114F50ACD2740030F4FFCB";
            if (sTemp.Length > len)
                sTemp = sTemp.Substring(0, len);
            else if (sTemp.Length < len)
                sTemp = sTemp.PadRight(len, ' ');
            return TransToByte(sTemp);
        }
        /// <summary>
        /// 获得加密向量
        /// </summary>
        /// <param name="len"></param>
        /// <returns></returns>
        private static byte[] GetLegalIV(int len)
        {
            string sTemp = "62E262EC547E48BE97FFB764EA3C0EAB";
            if (sTemp.Length > len)
                sTemp = sTemp.Substring(0, len);
            else if (sTemp.Length < len)
                sTemp = sTemp.PadRight(len, ' ');
            return TransToByte(sTemp);
        }

        #region SymmetricAlgorithm
        private static byte[] Encrypt(byte[] bytIn, SymmetricAlgorithm cryptoService)
        {
            using (ICryptoTransform encrypto = cryptoService.CreateEncryptor())
            {
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);
                cs.Write(bytIn, 0, bytIn.Length);
                cs.FlushFinalBlock();
                cs.Close();
                ms.Close();
                byte[] bytOut = ms.ToArray();
                return bytOut;
            }
        }

        private static byte[] Decryp(byte[] bytIn, SymmetricAlgorithm cryptoService)
        {
            using (ICryptoTransform encrypto = cryptoService.CreateDecryptor())
            {
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, encrypto, CryptoStreamMode.Write);
                cs.Write(bytIn, 0, bytIn.Length);
                cs.FlushFinalBlock();
                cs.Close();
                ms.Close();
                byte[] bytOut = ms.ToArray();
                return bytOut;
            }
        }

        #endregion

        #region AES
        /// <summary>
        /// AES字符串加密方法
        /// </summary>
        /// <param name="source"></param>
        /// <returns>Base64字符</returns>
        public static string AESEncryp(this string source)
        {
            byte[] bytIn = TransToByte(source);
            return Convert.ToBase64String(AESEncryp(bytIn));
        }
        /// <summary>
        /// AES字节数组加密方法
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static byte[] AESEncryp(this byte[] source)
        {
            return AESEncryp(source, GetLegalKey(32), GetLegalIV(16));
        }
        /// <summary>
        /// AES字节数组加密方法
        /// </summary>
        /// <param name="source"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public static byte[] AESEncryp(this byte[] source, byte[] key, byte[] iv)
        {
            SymmetricAlgorithm mobjCryptoService = new RijndaelManaged();
            mobjCryptoService.Key = GetLegalKey(32);
            mobjCryptoService.IV = GetLegalIV(16);
            return Encrypt(source, mobjCryptoService);
        }
        /// <summary>
        /// AES字符串解密方法
        /// </summary>
        /// <param name="source">Base64字符</param>
        /// <returns></returns>
        public static string AESDecryp(this string source)
        {
            byte[] bytIn = Convert.FromBase64String(source);
            return TransToString(AESDecryp(bytIn));
        }
        /// <summary>
        /// AES字节数组解密方法
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static byte[] AESDecryp(this byte[] source)
        {
            return AESDecryp(source, GetLegalKey(32), GetLegalIV(16));
        }
        /// <summary>
        /// AES字节数组解密方法
        /// </summary>
        /// <param name="source"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public static byte[] AESDecryp(this byte[] source, byte[] key, byte[] iv)
        {
            SymmetricAlgorithm mobjCryptoService = new RijndaelManaged();
            mobjCryptoService.Key = key;
            mobjCryptoService.IV = iv;
            return Decryp(source, mobjCryptoService);
        }
        #endregion

        #region DES
        /// <summary>
        /// DES字符串加密方法
        /// </summary>
        /// <param name="source"></param>
        /// <returns>Base64字符</returns>
        public static string DESEncryp(this string source)
        {
            byte[] bytIn = TransToByte(source);
            return Convert.ToBase64String(DESEncryp(bytIn));
        }
        /// <summary>
        /// DEC字节数组解密方法
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static byte[] DESEncryp(this byte[] source)
        {
            return DESEncryp(source, GetLegalKey(8), GetLegalIV(8));
        }
        /// <summary>
        /// DEC字节数组解密方法
        /// </summary>
        /// <param name="source"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public static byte[] DESEncryp(this byte[] source, byte[] key, byte[] iv)
        {
            SymmetricAlgorithm mobjCryptoService = new DESCryptoServiceProvider();
            mobjCryptoService.Key = key;
            mobjCryptoService.IV = iv;
            return Encrypt(source, mobjCryptoService);
        }

        /// <summary>
        /// DES字符串解密方法
        /// </summary>
        /// <param name="source">Base64字符</param>
        /// <returns></returns>
        public static string DESDecryp(this string source)
        {
            byte[] bytIn = Convert.FromBase64String(source);
            return TransToString(DESDecryp(bytIn));
        }
        /// <summary>
        /// DES字节数组解密方法
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static byte[] DESDecryp(this byte[] source)
        {
            return DESDecryp(source, GetLegalKey(8), GetLegalIV(8));
        }
        /// <summary>
        /// DES字节数组解密方法
        /// </summary>
        /// <param name="source"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public static byte[] DESDecryp(this byte[] source, byte[] key, byte[] iv)
        {
            SymmetricAlgorithm mobjCryptoService = new DESCryptoServiceProvider();
            mobjCryptoService.Key = key;
            mobjCryptoService.IV = iv;
            return Decryp(source, mobjCryptoService);
        }
        #endregion

        #region 3DES
        /// <summary>
        /// 3DES字符串加密方法
        /// </summary>
        /// <param name="source"></param>
        /// <returns>Base64字符</returns>
        public static string DES3Encryp(this string source)
        {
            byte[] bytIn = TransToByte(source);
            return Convert.ToBase64String(DES3Encryp(bytIn));
        }
        /// <summary>
        /// 3DES字节数组加密方法
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static byte[] DES3Encryp(this byte[] source)
        {
            return DES3Encryp(source, GetLegalKey(24), GetLegalIV(8));
        }
        /// <summary>
        /// 3DES字节数组加密方法
        /// </summary>
        /// <param name="source"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public static byte[] DES3Encryp(this byte[] source, byte[] key, byte[] iv)
        {
            SymmetricAlgorithm mobjCryptoService = new TripleDESCryptoServiceProvider();
            mobjCryptoService.Key = key;
            mobjCryptoService.IV = iv;
            return Encrypt(source, mobjCryptoService);
        }
        /// <summary>
        /// 3DES字符串解密方法
        /// </summary>
        /// <param name="source">Base64字符</param>
        /// <returns></returns>
        public static string DES3Decryp(this string source)
        {
            byte[] bytIn = Convert.FromBase64String(source);
            return TransToString(DES3Decryp(bytIn));
        }
        /// <summary>
        /// 3DES字节数组解密方法
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static byte[] DES3Decryp(this byte[] source)
        {
            return DES3Decryp(source, GetLegalKey(24), GetLegalIV(8));
        }
        /// <summary>
        /// 3DES字节数组解密方法
        /// </summary>
        /// <param name="source"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public static byte[] DES3Decryp(this byte[] source, byte[] key, byte[] iv)
        {
            SymmetricAlgorithm mobjCryptoService = new TripleDESCryptoServiceProvider();
            mobjCryptoService.Key = GetLegalKey(24);
            mobjCryptoService.IV = GetLegalIV(8);
            return Decryp(source, mobjCryptoService);
        }
        #endregion

        #region Simple
        /// <summary>
        /// Simple字符串加密方法
        /// </summary>
        /// <param name="source"></param>
        /// <returns>Base64字符</returns>
        public static string SimpleEncryp(this string source)
        {
            byte[] bytIn = TransToByte(source);
            return Convert.ToBase64String(SimpleEncryp(bytIn));
        }
        /// <summary>
        /// Simple字符串解密方法
        /// </summary>
        /// <param name="source">Base64字符</param>
        /// <returns></returns>
        public static string SimpleDecryp(this string source)
        {
            byte[] bytIn = Convert.FromBase64String(source);
            return TransToString(SimpleEncryp(bytIn));
        }
        /// <summary>
        /// Xor字节数组运算
        /// </summary>
        /// <param name="bytIn"></param>
        /// <returns></returns>
        public static byte[] SimpleEncryp(this byte[] bytIn)
        {
            byte[] key = GetLegalKey(24);
            int byteLen = key.Length;
            for (int i = 0; i < bytIn.Length; i++)
            {
                bytIn[i] = (byte)(bytIn[i] ^ key[i % byteLen]);
            }
            return bytIn;
        }

        #endregion

        #region HashAlgorithm
        /// <summary>
        /// MD5 散列函数
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string MD5Secret(this string source)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(source, "MD5");
        }
        /// <summary>
        /// SHA1 散列函数
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string SHA1Secret(this string source)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(source, "SHA1");
        }
        /// <summary>
        /// MD5 字节数组散列认证
        /// </summary>
        /// <param name="bytIn"></param>
        /// <returns></returns>
        public static byte[] HMACMD5(this byte[] bytIn)
        {
            byte[] key = GetLegalKey(32);
            HMACMD5 md5 = new HMACMD5(key);
            Byte[] bStream = md5.ComputeHash(bytIn);
            return bStream;
        }
        /// <summary>
        /// MD5 字符串散列认证
        /// </summary>
        /// <param name="source"></param>
        /// <returns>Base64字符</returns>
        public static string HMACMD5(this string source)
        {
            byte[] bytIn = TransToByte(source);
            return Convert.ToBase64String(HMACMD5(bytIn));
        }
        /// <summary>
        /// MD5 散列函数
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string MD5(this string source)
        {
            return MD5Secret(source);
        }
        /// <summary>
        /// SHA1 散列函数
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string SHA1(this string source)
        {
            return SHA1Secret(source);
        }

        /// <summary>
        /// 三次MD5加密
        /// </summary>
        /// <param name="source">需要加密的字符串</param>
        /// <returns></returns>
        public static string TMD5(this string source)
        {
            string A = MD5(source);
            string B = MD5(A);
            return MD5(B);
        }
        #endregion

        #region Base64
        /// <summary>
        /// 字符串Base64编码
        /// </summary>
        /// <param name="data"></param>
        /// <returns>Base64字符</returns>
        public static string Base64Encryp(this string data)
        {
            try
            {
                byte[] encDataByte = TransToByte(data);
                string encodedData = Convert.ToBase64String(encDataByte);
                return encodedData;
            }
            catch
            {
                return string.Empty;
            }
        }
        /// <summary>
        /// 字符串Base64解码
        /// </summary>
        /// <param name="data">Base64字符</param>
        /// <returns></returns>
        public static string Base64Decryp(this string data)
        {
            try
            {
                byte[] deData = Convert.FromBase64String(data);
                string result = TransToString(deData);
                return result;
            }
            catch
            {
                return string.Empty;
            }
        }

        #endregion
    }
}
